package com.north.light.libltobserver.impl;

import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

import com.north.light.libltobserver.bean.LTTrainBean;
import com.north.light.libltobserver.context.LTContextInfo;
import com.north.light.libltobserver.context.LTContextType;
import com.north.light.libltobserver.listener.LTObserverListener;
import com.north.light.libltobserver.pool.LTObserverPool;
import com.north.light.libltobserver.utils.LTClassType;
import com.north.light.libltobserver.utils.LTLogUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * FileName: LTObserverReceiver
 * Author: lzt
 * Date: 2022/11/15 14:34
 */
public class LTObserverReceiver implements Serializable {

    private LTContextInfo mContextInfo;
    //是否已经设置了声明周期的对象
    private final boolean isInit;
    //用户传入的tag--如果没有则取当前类名
    private String tag;
    //监听列表
    private final List<LTObserverListener<Object>> mListenerList = new ArrayList<>();
    //resume or pause
    private final AtomicBoolean mIsResume = new AtomicBoolean(false);
    //通知对象队列缓存
    private final CopyOnWriteArrayList<Object> mNotifyList = new CopyOnWriteArrayList<Object>();

    private final Object mLock = new Object();

    private LTContextInfo getContextObj() {
        if (this.mContextInfo == null) {
            mContextInfo = new LTContextInfo();
        }
        return mContextInfo;
    }

    public LTObserverReceiver(AppCompatActivity activity) {
        getContextObj().setActivity(activity);
        isInit = true;
    }

//    public LTObserverReceiver(Fragment fragment) {
//        getContextObj().setFragment(fragment);
//        isInit = true;
//    }

    //内部调用---------------------------------------------------------------------------

    private void setTag(String tag) {
        this.tag = tag;
    }

    private String getTag() {
        return tag;
    }

    public String getIdentify() {
        return (TextUtils.isEmpty(getTag()) ? getClassTag() : getTag());
    }

    private String getClassTag() {
        if (!TextUtils.isEmpty(getTag())) {
            return getTag();
        }
        int contextType = getContextObj().getContextType().getType();
        if (contextType == LTContextType.TYPE_X_ACTIVITY.getType()) {
            //activity type
            Class<?> cla = getContextObj().getActivity().getClass();
            String hashCode = Integer.toHexString(cla.hashCode());
            return cla.getSimpleName() + hashCode;
        }
//        else if (contextType == LTContextType.TYPE_X_FRAGMENT.getType()) {
//            //fragment type
//            Class<?> cla = getContextObj().getFragment().getClass();
//            String hashCode = Integer.toHexString(cla.hashCode());
//            return cla.getSimpleName() + hashCode;
//        }
        return null;
    }

    private Lifecycle getLifecycle() {
        int contextType = getContextObj().getContextType().getType();
        if (contextType == LTContextType.TYPE_X_ACTIVITY.getType()) {
            //activity type
            return getContextObj().getActivity().getLifecycle();
        }
//        else if (contextType == LTContextType.TYPE_X_FRAGMENT.getType()) {
//            //fragment type
//            return getContextObj().getFragment().getLifecycle();
//        }
        return null;
    }


    //内部生命周期处理
    private void lifecycleEvent(LifecycleOwner source, Lifecycle.Event event) {
        if (source == null || event == null) {
            return;
        }
        String eventName = event.name();
        String resumeName = Lifecycle.Event.ON_RESUME.name();
        String pauseName = Lifecycle.Event.ON_PAUSE.name();
        String destroyName = Lifecycle.Event.ON_DESTROY.name();
        if (resumeName.equals(eventName)) {
            //恢复
            mIsResume.set(true);
            //检查数据，通知外部
            checkAndNotify();
        } else if (pauseName.equals(eventName)) {
            //暂停
            mIsResume.set(false);
        } else if (destroyName.equals(eventName)) {
            //停止
            //释放对象
            cancel();
        }
    }

    //取消
    private void cancel(String tag) {
        //移除复用对象
        LTObserverPool.getInstance().remove(tag);
        removeCallbackListener();
    }

    //取消
    private void cancel() {
        cancel(getIdentify());
    }

    private void removeCallbackListener() {
        mListenerList.clear();
    }

    public synchronized CopyOnWriteArrayList<Object> getNotifyList() {
        return mNotifyList;
    }

    /**
     * 检查数据，通知外部
     */
    private void checkAndNotify() {
        synchronized (mLock) {
            if (mListenerList.size() != 0 && getNotifyList().size() != 0) {
                List<Integer> posRemove = new ArrayList<>();
                for (int i = 0; i < getNotifyList().size(); i++) {
                    if (!mIsResume.get()) {
                        break;
                    }
                    notifyInfo(getNotifyList().get(i));
                    //缓存记录
                    posRemove.add(i);
                }
                if (posRemove.size() == 0) {
                    return;
                }
                Map<Integer, LTTrainBean<Object>> mapInfo = new HashMap<>();
                for (int i = 0; i < getNotifyList().size(); i++) {
                    LTTrainBean<Object> trainBean = new LTTrainBean<>();
                    trainBean.setPos(i);
                    trainBean.setT(getNotifyList().get(i));
                    mapInfo.put(i, trainBean);
                }
                for (int i = 0; i < posRemove.size(); i++) {
                    mapInfo.remove(i);
                }
                //转行map到list
                if (mapInfo.size() == 0) {
                    getNotifyList().clear();
                    return;
                }
                CopyOnWriteArrayList<LTTrainBean<Object>> trainList = new CopyOnWriteArrayList<>();
                for (Map.Entry<Integer, LTTrainBean<Object>> mapCache : mapInfo.entrySet()) {
                    trainList.add(mapCache.getValue());
                }
                Collections.sort(trainList, new Comparator<LTTrainBean<Object>>() {
                    @Override
                    public int compare(LTTrainBean<Object> o1, LTTrainBean<Object> o2) {
                        return o1.getPos() - o2.getPos();
                    }
                });
                CopyOnWriteArrayList<Object> finalList = new CopyOnWriteArrayList<>();
                for (int i = 0; i < trainList.size(); i++) {
                    finalList.add(finalList.size(), trainList.get(i));
                }
                getNotifyList().clear();
                getNotifyList().addAll(finalList);
            }
        }
    }

    /**
     * 通知
     */
    private <T> void notifyInfo(T t) {
        for (LTObserverListener<Object> listener : mListenerList) {
            if (listener == null) {
                LTLogUtil.d("listener is null");
                continue;
            }
            Class<?> listenerType = LTClassType.getInstance(listener);
            if (listenerType == null) {
                LTLogUtil.d("listener type ignore");
                continue;
            }
            String lName = listenerType.getName();
            String typeName = t.getClass().getName();
            if (TextUtils.isEmpty(lName) || TextUtils.isEmpty(typeName)) {
                continue;
            }
            if (lName.equals(typeName)) {
                //通知外部--先放入map，再调用监听--生命周期管控
                listener.callback(t);
            }
        }
    }

    private final LifecycleObserver lifecycleOwner = new LifecycleEventObserver() {
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            String name = source.getClass().getSimpleName();
            LTLogUtil.d("lifecycleOwner: " + event.name() + " name: " + name);
            lifecycleEvent(source, event);
        }
    };

    //外部调用---------------------------------------------------------------------------


    //设置标识
    public LTObserverReceiver setIdentify(String tag) {
        setTag(tag);
        return this;
    }

    //设置监听
    public LTObserverReceiver setCallBackListener(LTObserverListener listener) {
        if (listener == null) {
            return this;
        }
        mListenerList.add(listener);
        return this;
    }

    //最后调用
    public void build() {
        if (!isInit) {
            return;
        }
        String identify = getIdentify();
        setTag(identify);
        Lifecycle lifecycle = getLifecycle();
        if (lifecycle != null) {
            lifecycle.addObserver(lifecycleOwner);
        }
        //添加复用对象
        LTObserverPool.getInstance().add(identify, this);
    }

    /**
     * 发送
     */
    public <T> void send(T t) {
        synchronized (mLock) {
            if (!isInit || mListenerList == null || mListenerList.size() == 0) {
                return;
            }
            if (!mIsResume.get() || getNotifyList().size() != 0) {
                //不在resume
                getNotifyList().add(getNotifyList().size(), t);
                return;
            }
            //在resume情况下,队列没有数据情况下，直接通知
            notifyInfo(t);
        }
    }
}
